﻿using System;
using System.Collections.ObjectModel;
using System.ComponentModel;

using Matchingo.Common.Types.Types;
using Matchingo.Common.Types.EventArguments;

namespace Matchingo.Common.Types.Interfaces
{
    public interface IMemoryGameLogic : INotifyPropertyChanged
    {
        #region ========== Public Properties ==========

        /// <summary>
        /// the number of columns to use in the card grid for the current game
        /// </summary>
        int GridColumns { get; }

        /// <summary>
        /// the number of rows to use in the card grid for the current game      
        /// </summary>
        int GridRows { get; }

        /// <summary>
        /// the current combo count (number of matches done consecutively)
        /// </summary>
        int MatchComboCount { get; }

        /// <summary>
        /// the current game in progress
        /// </summary>
        Game CurrentGame { get; }

        #endregion

        #region ========== Public Methods ==========

        /// <summary>
        /// Must be called before accessing any other properties/methods/etc.
        /// </summary>
        void Initialize();

        /// <summary>
        /// Starts a new game
        /// </summary>
        /// <param name="settings">The settings from which the new game will be based</param>
        void StartNewGame(MatchGameSettings settings);

        /// <summary>
        /// Starts a new game
        /// </summary>
        /// <param name="settings">The settings from which the new game will be based</param>
        /// <param name="replayCards">The cards from which to play the game with (used for replays where the card IDs must be the same as recorded in the game being played back)</param>
        void StartNewGame(MatchGameSettings settings, ObservableCollection<Card> replayCards);

        /// <summary>
        /// Request to flip over a given card
        /// </summary>
        /// <param name="uniqueCardID">The uniqueID of the Card to try and flip over</param>
        /// <returns>Whether or not the card actually flipped (card requested may not be able to flip, etc.)</returns>
        bool Flip(Guid uniqueCardID);

        #endregion

        #region ========== Public Events ==========

        /// <summary>
        /// Fired when two cards are flipped over which match
        /// </summary>
        event EventHandler<MatchEventArgs> CardsMatched;

        /// <summary>
        /// Fired whenever the combo count (number of consecutive matches) changes
        /// </summary>
        event EventHandler MatchComboCountChanged;

        #endregion
    }
}
